#!/bin/bash
# RedFire Kubernetes 集群初始化脚本
# ================================
# 
# 初始化Kubernetes集群，包括：
# - 创建命名空间
# - 部署基础设施服务
# - 配置监控系统
# - 设置网络策略和RBAC

set -euo pipefail

# 脚本配置
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
KUBE_DIR="$(dirname "$SCRIPT_DIR")/kubernetes"
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# 检查依赖
check_dependencies() {
    log_info "检查依赖工具..."
    
    local deps=("kubectl" "helm" "jq")
    for dep in "${deps[@]}"; do
        if ! command -v "$dep" &> /dev/null; then
            log_error "缺少依赖工具: $dep"
            exit 1
        fi
    done
    
    if ! kubectl cluster-info &> /dev/null; then
        log_error "无法连接到Kubernetes集群"
        exit 1
    fi
    
    log_success "依赖检查通过"
}

# 创建命名空间
create_namespaces() {
    log_info "创建命名空间..."
    
    kubectl apply -f "$KUBE_DIR/namespace.yaml"
    
    log_success "命名空间创建完成"
}

# 创建密钥
create_secrets() {
    log_info "创建密钥..."
    
    # 检查是否存在密钥文件
    if [[ -f "$KUBE_DIR/secrets.yaml" ]]; then
        log_warning "使用模板密钥文件，生产环境请替换为真实密钥"
        kubectl apply -f "$KUBE_DIR/secrets.yaml"
    else
        log_warning "未找到密钥文件，跳过密钥创建"
    fi
    
    log_success "密钥创建完成"
}

# 部署基础设施服务
deploy_infrastructure() {
    log_info "部署基础设施服务..."
    
    # 添加Helm仓库
    log_info "添加Helm仓库..."
    helm repo add bitnami https://charts.bitnami.com/bitnami
    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    helm repo add grafana https://grafana.github.io/helm-charts
    helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
    helm repo update
    
    # 部署PostgreSQL
    log_info "部署PostgreSQL..."
    helm upgrade --install postgres bitnami/postgresql \
        --namespace redfire-prod \
        --set auth.postgresPassword=redfire123 \
        --set auth.database=redfire \
        --set primary.persistence.size=20Gi \
        --set primary.resources.requests.memory=1Gi \
        --set primary.resources.requests.cpu=500m \
        --wait
    
    # 部署Redis
    log_info "部署Redis..."
    helm upgrade --install redis bitnami/redis \
        --namespace redfire-prod \
        --set auth.password=redis123 \
        --set master.persistence.size=10Gi \
        --set master.resources.requests.memory=512Mi \
        --set master.resources.requests.cpu=250m \
        --wait
    
    # 部署RabbitMQ
    log_info "部署RabbitMQ..."
    helm upgrade --install rabbitmq bitnami/rabbitmq \
        --namespace redfire-prod \
        --set auth.username=redfire \
        --set auth.password=rabbitmq123 \
        --set persistence.size=10Gi \
        --set resources.requests.memory=512Mi \
        --set resources.requests.cpu=250m \
        --wait
    
    log_success "基础设施服务部署完成"
}

# 部署监控系统
deploy_monitoring() {
    log_info "部署监控系统..."
    
    # 创建监控命名空间
    kubectl create namespace redfire-monitoring --dry-run=client -o yaml | kubectl apply -f -
    
    # 部署Prometheus
    log_info "部署Prometheus..."
    helm upgrade --install prometheus prometheus-community/kube-prometheus-stack \
        --namespace redfire-monitoring \
        --set prometheus.prometheusSpec.retention=30d \
        --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi \
        --set grafana.adminPassword=admin123 \
        --set grafana.persistence.enabled=true \
        --set grafana.persistence.size=10Gi \
        --wait
    
    # 部署Jaeger
    log_info "部署Jaeger..."
    helm upgrade --install jaeger jaegertracing/jaeger \
        --namespace redfire-monitoring \
        --set provisionDataStore.cassandra=false \
        --set storage.type=memory \
        --set agent.enabled=true \
        --set collector.enabled=true \
        --set query.enabled=true \
        --wait
    
    log_success "监控系统部署完成"
}

# 应用配置
apply_configs() {
    log_info "应用配置文件..."
    
    kubectl apply -f "$KUBE_DIR/configmap.yaml"
    
    log_success "配置应用完成"
}

# 部署应用服务
deploy_applications() {
    log_info "部署应用服务..."
    
    # 应用蓝绿部署配置
    kubectl apply -f "$KUBE_DIR/blue-green-deployment.yaml"
    
    # 等待部署完成
    log_info "等待应用服务就绪..."
    kubectl wait --for=condition=available --timeout=600s deployment/gateway-blue -n redfire-prod
    kubectl wait --for=condition=available --timeout=600s deployment/alpha-engine-blue -n redfire-prod
    
    log_success "应用服务部署完成"
}

# 配置网络策略
configure_network_policies() {
    log_info "配置网络策略..."
    
    cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: redfire-network-policy
  namespace: redfire-prod
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: redfire-prod
    - namespaceSelector:
        matchLabels:
          name: redfire-monitoring
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: redfire-prod
    - namespaceSelector:
        matchLabels:
          name: redfire-monitoring
  - to: []
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 443
EOF
    
    log_success "网络策略配置完成"
}

# 配置RBAC
configure_rbac() {
    log_info "配置RBAC..."
    
    cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: redfire-service-account
  namespace: redfire-prod
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: redfire-prod
  name: redfire-role
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: redfire-rolebinding
  namespace: redfire-prod
subjects:
- kind: ServiceAccount
  name: redfire-service-account
  namespace: redfire-prod
roleRef:
  kind: Role
  name: redfire-role
  apiGroup: rbac.authorization.k8s.io
EOF
    
    log_success "RBAC配置完成"
}

# 验证部署
verify_deployment() {
    log_info "验证部署状态..."
    
    echo "============================================"
    echo "命名空间状态:"
    kubectl get namespaces | grep redfire
    
    echo ""
    echo "基础设施服务状态:"
    kubectl get pods -n redfire-prod | grep -E "(postgres|redis|rabbitmq)"
    
    echo ""
    echo "应用服务状态:"
    kubectl get deployments -n redfire-prod
    
    echo ""
    echo "监控系统状态:"
    kubectl get pods -n redfire-monitoring
    
    echo ""
    echo "服务端点:"
    kubectl get services -n redfire-prod
    kubectl get services -n redfire-monitoring
    
    echo "============================================"
    
    log_success "部署验证完成"
}

# 显示访问信息
show_access_info() {
    log_info "获取访问信息..."
    
    echo "============================================"
    echo "RedFire 集群访问信息"
    echo "============================================"
    
    # 获取Grafana访问信息
    local grafana_password=$(kubectl get secret --namespace redfire-monitoring prometheus-grafana -o jsonpath="{.data.admin-password}" | base64 --decode)
    echo "Grafana:"
    echo "  URL: http://localhost:3000 (需要端口转发)"
    echo "  用户名: admin"
    echo "  密码: $grafana_password"
    echo "  端口转发: kubectl port-forward service/prometheus-grafana 3000:80 -n redfire-monitoring"
    
    echo ""
    echo "Prometheus:"
    echo "  URL: http://localhost:9090 (需要端口转发)"
    echo "  端口转发: kubectl port-forward service/prometheus-kube-prometheus-prometheus 9090:9090 -n redfire-monitoring"
    
    echo ""
    echo "Jaeger:"
    echo "  URL: http://localhost:16686 (需要端口转发)"
    echo "  端口转发: kubectl port-forward service/jaeger-query 16686:16686 -n redfire-monitoring"
    
    echo ""
    echo "RedFire API:"
    echo "  URL: http://localhost:8000 (需要端口转发)"
    echo "  端口转发: kubectl port-forward service/gateway-service 8000:8000 -n redfire-prod"
    
    echo "============================================"
}

# 清理集群
cleanup_cluster() {
    log_warning "开始清理集群..."
    
    read -p "确认要删除所有RedFire资源吗? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        kubectl delete namespace redfire-prod --ignore-not-found=true
        kubectl delete namespace redfire-dev --ignore-not-found=true
        kubectl delete namespace redfire-monitoring --ignore-not-found=true
        
        log_success "集群清理完成"
    else
        log_info "取消清理操作"
    fi
}

# 显示帮助信息
show_help() {
    cat << EOF
RedFire Kubernetes 集群管理脚本

使用方法:
  $0 setup                # 完整集群初始化
  $0 infrastructure       # 仅部署基础设施
  $0 monitoring          # 仅部署监控系统
  $0 applications        # 仅部署应用服务
  $0 verify              # 验证部署状态
  $0 access-info         # 显示访问信息
  $0 cleanup             # 清理集群
  $0 help                # 显示帮助信息

组件说明:
  infrastructure: PostgreSQL, Redis, RabbitMQ
  monitoring: Prometheus, Grafana, Jaeger
  applications: Gateway, Alpha Engine, Chart Engine, VnPy Engine

EOF
}

# 主函数
main() {
    if [[ $# -eq 0 ]]; then
        show_help
        exit 1
    fi
    
    local command=$1
    
    check_dependencies
    
    case $command in
        setup)
            log_info "开始完整集群初始化..."
            create_namespaces
            create_secrets
            apply_configs
            deploy_infrastructure
            deploy_monitoring
            configure_network_policies
            configure_rbac
            deploy_applications
            verify_deployment
            show_access_info
            log_success "集群初始化完成"
            ;;
        infrastructure)
            create_namespaces
            create_secrets
            apply_configs
            deploy_infrastructure
            ;;
        monitoring)
            deploy_monitoring
            ;;
        applications)
            deploy_applications
            ;;
        verify)
            verify_deployment
            ;;
        access-info)
            show_access_info
            ;;
        cleanup)
            cleanup_cluster
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            log_error "未知命令: $command"
            show_help
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"
